﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Netra
{
    class Store
    {
        private class CInfo
        {
            public int Quantity;
            public int MaxQuantity;
            public int ProduceQuan;
            public int ConsumeQuan;
            public int BuyPrice;
            public int SellPrice;

            public CInfo(int quantity, int maxquantity, int prodquantity, int consquantity, int buyprice, int sellprice)
            {
                Quantity = quantity;
                MaxQuantity = maxquantity;
                ProduceQuan = prodquantity;
                ConsumeQuan = consquantity;
                BuyPrice = buyprice;
                SellPrice = sellprice;
            }

            public override string ToString()
            {
                return "stock:" + Quantity.ToString() + ", max:" + MaxQuantity.ToString() + ", prod:" + ProduceQuan.ToString()+", cons:"+ConsumeQuan.ToString() + ", sell:" + SellPrice.ToString() + ", buy:" + BuyPrice.ToString();
            }
        }
        private Dictionary<Merch,CInfo> merchs;

        //private int this[Merch towar]
        //{
        //    get
        //    {
        //        if (!merchs.ContainsKey(towar))
        //            merchs[towar] = 0;
        //        return merchs[towar];
        //    }
        //    set
        //    {
        //        merchs[towar] = value;
        //    }

        //}

        public Store()
        {
            merchs = new Dictionary<Merch, CInfo>();
        }

        public void GenerateProduction()
        {

            foreach (CInfo wi in merchs.Values)
            {
                wi.Quantity += wi.ProduceQuan;
                if (wi.Quantity > wi.MaxQuantity)
                    wi.Quantity = wi.MaxQuantity;
            }
        }

        public bool Trades(Merch ware)
        {
            return merchs.ContainsKey(ware);
        }

        public void AddProduction(Merch ware,int price, int prodquantity)
        {
            CInfo wareinfo;
            if ((Trades(ware))&&(merchs[ware].SellPrice>0))
                wareinfo = merchs[ware];
            else
                merchs[ware] = wareinfo = new CInfo(quantity:0,maxquantity:0,buyprice:0,prodquantity:0,sellprice:0,consquantity:0);
            wareinfo.SellPrice = price;
            wareinfo.ProduceQuan += prodquantity;
            wareinfo.MaxQuantity += 4 * prodquantity;
            wareinfo.Quantity += 4*prodquantity;

        }
        public void AddDemand(Merch ware, int consquantity, int price)
        {
            CInfo wareinfo;
            if ((Trades(ware))&&(merchs[ware].BuyPrice>0))
            {
                wareinfo = merchs[ware];
            }
            else
                merchs[ware] = wareinfo = new CInfo(quantity: 0, maxquantity: 0, buyprice: 0, prodquantity: 0, sellprice: 0,consquantity:0);

            wareinfo.MaxQuantity += 4*consquantity;
            wareinfo.ConsumeQuan += consquantity;
            wareinfo.BuyPrice = price;
            wareinfo.Quantity = 0;

        }


        public int MaxSellQuantity(Merch ware)
        {
            if (Trades(ware))
            {
                CInfo wareinfo=merchs[ware];
                if (wareinfo.SellPrice > 0)
                    return wareinfo.Quantity;
                else
                    return 0;
            }
            else
                return 0;
        }

        public int MaxBuyQuantity(Merch ware)
        {
            if (Trades(ware))
            {
                CInfo wareinfo = merchs[ware];
                if (wareinfo.BuyPrice > 0)
                    return wareinfo.MaxQuantity - wareinfo.Quantity;
                else
                    return 0;
            }
            else
                return 0;
        }

        public void Sell(Merch ware,int quantity)
        {
            if (Trades(ware))
            {
                if (MaxSellQuantity(ware) >= quantity)
                {
                    merchs[ware].Quantity += quantity;
                }
                else
                    throw new System.ArgumentException("Cannot sell, quantity too big", "quantity");
            }
            else
                throw new System.ArgumentException("Store does not trade the ware", "ware");
        }

        public void Buy(Merch ware, int quantity)
        {
            if (merchs.ContainsKey(ware))
            {
                if (merchs[ware].Quantity >= quantity)
                {
                    merchs[ware].Quantity -= quantity;
                    return;
                }
                else
                {
                    throw new System.ArgumentException("Cannot buy more ware than available", "quantity");
                }
            }
            throw new System.ArgumentException("Cannot buy ware, it is not available", "ware");
        }

        public int Production(Merch ware)
        {
            if (Trades(ware))
                return merchs[ware].ProduceQuan;
            else
                return 0;
        }

        public int Consumption(Merch ware)
        {
            if (Trades(ware))
                return merchs[ware].ConsumeQuan;
            else
                return 0;
        }


        public int SellPrice(Merch ware)
        {
            if (Trades(ware))
                return merchs[ware].SellPrice;
            else
                return 0;
        }

        public int BuyPrice(Merch ware)
        {
            if (Trades(ware))
                return merchs[ware].BuyPrice;
            else
                return 0;
        }

        public bool Offers(Merch ware)
        {
            if (!Trades(ware))
                return false;
            if (merchs[ware].SellPrice > 0)
                return true;
            else
                return false;
        }

        public bool Purchases(Merch ware)
        {
            if (!Trades(ware))
                return false;
            if (merchs[ware].BuyPrice > 0)
                return true;
            else
                return false;
        }

        public List<Merch> OfferedWares()
        {
            List<Merch> list = new List<Merch>();
            foreach (Merch ware in Merch.Goods)
                if (Offers(ware))
                    list.Add(ware);
            return list;
        }

        public List<Merch> PurchasedWares()
        {
            List<Merch> list = new List<Merch>();
            foreach (Merch ware in Merch.Goods)
                if (Purchases(ware))
                    list.Add(ware);
            return list;
        }

        #region properties

        #endregion properties

        public override string ToString()
        {
            string s="";
            foreach(KeyValuePair<Merch,CInfo> kvp in merchs)
            {
                s+=kvp.Key.Name+" "+kvp.Value.ToString()+"\n";
            }
            return s;
        }

    }
}
